function wizardModel(wizardId){
    var wdt, syntIdCount = 0, hasChanges = false;
    var $wizardTable = $('.wizard-table');
    
    function calcStepNumbers(){
        $wizardTable.find('tr[type=step]').each(function(i, o){
            $(o).find('td:eq(0)').text(i+1);
        });
    }
    
    function isValidStep(title){
        var isValid = true;
        $wizardTable.find('tr[type=step]').each(function(i, o){
            if($(o).find('td:eq(1)').text()==title) isValid = false;
        });
        return isValid;
    }
                
    // prepares Step buttons
    var $addStep = uic.element.button({
        hint: 'Add Step',
        icon: 'icon-plus',
        primary: true,
        onclick: function(){
            var $selected = wdt.getSelected();
            
            dialogManager.open({
                url: "manager/wizard/s/a",
                width: 500,
                resizable: false,
                title: 'Add Step',
                callback: function(o){
                    if(!o) return;
                    console.log(o);
                    if(!isValidStep(o.title)){
                        Notifier.warning('Other step has the same name', '\''+o.title+'\' step can\'t be added.');
                        return;
                    }
                    
                    var $row = $('<tr>').attr('id', '#'+syntIdCount).attr('type', 'step').addClass('success');
                    var $num = $('<td>');
                    var $name = $('<td>').text(o.title);
                    $row.append($num).append($name);
                    
                    hasChanges = true;
                    wdt.update(function(){
                        if($selected.size()>0){
                            var id;
                            if($selected.attr('type')=='step'){
                                id = $selected.attr('id');
                            } else {
                                id = $selected.attr('stepId');
                            }

                            var $stepFields = $wizardTable.find('tr[stepId='+id+']');
                            if($stepFields.size()>0) {
                                $stepFields.last().after($row);
                            } else {
                                $selected.after($row);
                            }
                        } else {
                            $wizardTable.append($row);
                        }
                        calcStepNumbers();
                    });
                    syntIdCount++;
                }
            })
        }
    }).getElement();

    var $editStep = uic.element.button({
        hint: 'Edit Step',
        icon: 'icon-pencil',
        onclick: function(){
            var $row = wdt.getSelected();
            if($row.size()==0) return;

            dialogManager.open({
                url: "manager/wizard/s/a",
                width: 500,
                data: {
                    title: $row.find('td:eq(1)').text()
                },
                resizable: false,
                title: 'Edit Step',
                callback: function(o){
                    if(!o) return;
                    console.log(o);
                    if(!isValidStep(o.title)){
                        Notifier.warning('Other step has the same name', '\''+o.title+'\' step can\'t be updated.');
                        return;
                    }
                    hasChanges = $row.find('td:eq(1)').text()!=o.title;
                    $row.find('td:eq(1)').text(o.title)
                    wdt.update();
                }
            })
        }
    }).getElement();

    var $deleteStep = uic.element.button({
        hint: 'Delete Step',
        icon: 'icon-trash',
        onclick: function(){
            var $row = wdt.getSelected();
            if($row.size()==0) return;

            hasChanges = true;
            wdt.update(function(){
                $wizardTable.find('tr[stepId='+$row.attr('id')+']').remove();
                $row.remove();
                calcStepNumbers();
            });
        }
    }).getElement();

    // prepares Field buttons
    function isValidField(id){
        return !$wizardTable.find('tr[type=field][id='+id+']').size()>0;
    }
    
    var $addField = uic.element.button({
        hint: 'Add Field',
        icon: 'icon-plus',
        primary: true,
        onclick: function(){
            var $selected = wdt.getSelected();
            if($selected.size()==0) return;
            var isStep = $selected.attr('type')=='step';
            dialogManager.open({
                url: "manager/wizard/f/a",
                width: 500,
                resizable: false,
                title: 'Add Field',
                callback: function(o){
                    if(!o) return;
                    console.log(o);
                    if(!isValidField(o.id)){
                        Notifier.warning('The field has been already using.', '\''+o.title+'\' field can\'t be selected.');
                        return;
                    }
                    hasChanges = true;
                    var $row = $('<tr>').attr('id', o.id).attr('type', 'field').addClass('info').attr('stepId', isStep ? $selected.attr('id') : $selected.attr('stepId') );
                    var $num = $('<td>').text('-');
                    var $name = $('<td>').text(o.title);
                    $row.append($num).append($name);
                    wdt.update(function(){
                        console.log('update')
                        if(isStep){
                            var $stepFields = $wizardTable.find('tr[stepId='+$selected.attr('id')+']');
                            if($stepFields.size()>0) {
                                $stepFields.last().after($row);
                            } else {
                                $selected.after($row);
                            }
                        } else {
                            $selected.after($row);
                        }
                        
                    });
                }
            })
        }
    }).getElement();

    var $editField = uic.element.button({
        hint: 'Edit Field',
        icon: 'icon-pencil',
        onclick: function(){
            var $selected = wdt.getSelected();
            if($selected.size()==0) return;
            
            dialogManager.open({
                url: "manager/wizard/f/a",
                data: {
                    id: $selected.attr('id')
                },
                width: 500,
                resizable: false,
                title: 'Edit Field',
                callback: function(o){
                    if(!o) return;
                    console.log(o);
                    if(!isValidField(o.id)){
                        Notifier.warning('The field has been already using.', '\''+o.title+'\' field can\'t be selected.');
                        return;
                    }
                    
                    hasChanges = $selected.attr('id')!=o.id;
                    $selected.attr('id', o.id);
                    $selected.find('td:eq(1)').text(o.title)
                    wdt.update();
                }
            })
        }
    }).getElement();

    var $deleteField = uic.element.button({
        hint: 'Delete Field',
        icon: 'icon-trash',
        onclick: function(){
            var $row = wdt.getSelected();
            if($row.size()==0) return;

            hasChanges = true;
            wdt.update(function(){
                $row.remove();
            });
        }
    }).getElement();
    
    var $saveButton = uic.element.button({
        title: 'Save changes',
        classes: 'btn-success',
        onclick: function(){
            // gathering steps
            var steps = new Array();
            $wizardTable.find('tr[type=step]').each(function(i, o){
                var $step = $(o);
                var id = $step.attr('id');
                
                // gathering step fields
                var fields = new Array();
                $wizardTable.find('tr[stepId='+id+']').each(function(i, o){
                    var $field = $(o);
                    // adds field
                    fields.push({
                        id: $field.attr('id')
                    });
                })
                
                // adds step
                steps.push({
                    id: id.indexOf('#')>-1 ? null : id,
                    title: $step.find('td:eq(1)').text(),
                    fields: fields
                })
            })
            
            var wizard = JSON.stringify({
                id: wizardId,
                steps: steps
            })
            console.log(wizard);
            
            $.ajax({
                url: 'save',
                data: {
                    wizard: wizard
                },
                type: "POST",
                success: function(data) {
                    Notifier.info(data);
                }
            });
            hasChanges = false;
            wdt.update();
            $wizardTable.find('tr').removeClass('success info');
        }
    }).getElement();

    wdt = new DataTable({
        autorefresh: false,
        table: $wizardTable,
        target: $('div#step-holder'),
        selectable: true,
        buttonGroups: [
            [$addStep, $editStep, $deleteStep],
            [$addField, $editField, $deleteField],
            [$saveButton]
        ],
        options: {
            bPaginate: false,
            bLengthChange: false,
            bFilter: false,
            bSort: false,
            bInfo: true,
            bAutoWidth: true
        },
        updateToolbar: function(){
            var setButtonsEnabled = function(isStepEnabled, isFieldEnabled){
                $editStep[0].wrapper.setEnabled(isStepEnabled);
                $deleteStep[0].wrapper.setEnabled(isStepEnabled);
                $addField[0].wrapper.setEnabled(isStepEnabled || isFieldEnabled);
                $editField[0].wrapper.setEnabled(isFieldEnabled);
                $deleteField[0].wrapper.setEnabled(isFieldEnabled);
                $saveButton[0].wrapper.setEnabled(hasChanges);
            }
            if(!wdt) {
                setButtonsEnabled(false, false);
                return;
            }
            var $selected = wdt.getSelected();
            var hasSelected = $selected.size()>0;

            if(hasSelected){
                var isStep = $selected.attr('type')=='step';
                if(isStep){
                    setButtonsEnabled(true, false);
                } else{
                    setButtonsEnabled(false, true);
                }
            } else {
                setButtonsEnabled(false, false);
            }
        }
    })
    $('#step-holder > .sidebar-container > .sidebar.sidebar-inner:eq(1)').css('height',490).css('overflow-y', 'auto');
    wdt.update();
    calcStepNumbers();
}